package com.netscenery.yang.designer;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.ArrayList;

import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import com.netscenery.util.ErrTag;
import com.netscenery.util.FileUtil;
import com.netscenery.yang.YangStatement;
import com.netscenery.yang.model.Env;
import com.netscenery.yang.model.MainModule;
import com.netscenery.yang.model.ModelElement;
import com.netscenery.yang.model.ModelException;
import com.netscenery.yang.model.Module;
import com.netscenery.yang.model.SubModule;
import com.netscenery.yang.model.Validator;
import com.netscenery.yang.parser.YangParser;
import com.netscenery.yang.parser.YangParserEnv;
import com.netscenery.yang.parser.YangParserException;
import com.netscenery.yang.writer.YangFormatter;



public class Action {
	public static final String FORMAT_YANG = "yang";
	public static final String FORMAT_XML = "xml";
	public static final String FORMAT_YIN = "yin";

	public static Module readYangModule(String module, Env env) {
		if (null == module) {
			return null;
		}
		Module imp = null;
		String yangStr = module;

		YangParser parser = new YangParser(yangStr);

		YangParserEnv parserEnv = parser.getEnv();
		parserEnv.setBeginColumn(1);
		parserEnv.setBeginLine(1);
		parserEnv.setBeginPos(0);
		parserEnv.setEndPos(yangStr.length());

		YangStatement statement = null;
		try {
			parser.parseYang();
		} catch (YangParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println(e.toString());
			return null;
		}
		statement = parser.getStatement();
		if (null == statement) {
			return null;
		}
		try {
			ModelElement me;
			try {
				me = ModelElement.parseYANG(env, statement);
				if (me instanceof MainModule) {
					imp = (MainModule) me;
				} else if (me instanceof SubModule) {
					imp = (SubModule) me;
				} else {
					return null;
				}
			} catch (ModelException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			

		} catch (YangParserException e1) {
			// TODO Auto-generated catch block

			if (e1.getErrorTag().equals(ErrTag.ERROR)) {
				e1.printStackTrace();
				return null;
			}

			System.out.println(e1.toString());
		}
		return imp;
	}
	
	public static Module readYangModule(File file, Env env) {
		if (null == file) {
			return null;
		}
		
		Module imp = null;
		String yangStr = null;
		try {
			yangStr = FileUtil.readFile2String(file);
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}

		YangParser parser = new YangParser(yangStr);

		YangParserEnv parserEnv = parser.getEnv();
		parserEnv.setBeginColumn(1);
		parserEnv.setBeginLine(1);
		parserEnv.setBeginPos(0);
		parserEnv.setEndPos(yangStr.length());
		parserEnv.setFilename(file.getAbsolutePath());

		YangStatement statement = null;
		try {
			parser.parseYang();
		} catch (YangParserException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			System.out.println(e.toString());
			if (e.getErrorTag() == ErrTag.ERROR){
				return null;
			}
			
			
		}
		statement = parser.getStatement();
		if (null == statement) {
			return null;
		}
		try {
			ModelElement me;
			try {
				me = ModelElement.parseYANG(env, statement);
				if (me instanceof MainModule) {
					imp = (MainModule) me;
				} else if (me instanceof SubModule) {
					imp = (SubModule) me;
				} else {
					return null;
				}
			} catch (ModelException e) {
				// TODO Auto-generated catch block
				System.out.println(e.toString());
				if (e.getErrorTag() == ErrTag.ERROR){
					return null;
				}			
			}
			

		} catch (YangParserException e1) {
			// TODO Auto-generated catch block
			System.out.println(e1.toString());
			if (e1.getErrorTag().equals(ErrTag.ERROR)) {
				
				return null;
			}

			
		}
		return imp;
	}
    // FEFF because this is the Unicode char represented by the UTF-8 byte order mark (EF BB BF).
    private static final String UTF8_BOM = "\uFEFF";

    private static String removeUTF8BOM(String s) {
        if (s.startsWith(UTF8_BOM)) {
            s = s.substring(1);
        }
        return s;
    }

	public static Module readXMLModule(String module, Env env) {
		if (null == module) {
			return null;
		}
		Module imp = null;
		Document doc = null;
		SAXBuilder sax = new SAXBuilder();
		module = removeUTF8BOM(module);
		StringReader sr = new StringReader(module);
		try {
			doc = sax.build(sr);
		} catch (JDOMException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		if (null == doc) {
			return null;
		}

		ModelElement me = null;
		try {
			me = ModelElement.parseXML(env, doc.getRootElement());
		} catch (ModelException e1) {
			if (e1.getErrorTag().equals(ErrTag.ERROR)) {
				e1.printStackTrace();
				return null;
			}

			System.out.println(e1.toString());
		}
		if (null == me) {
			return null;
		}
		if (me instanceof MainModule) {
			imp = (MainModule) me;
		} else if (me instanceof SubModule) {
			imp = (SubModule) me;
		} else {
			return null;
		}
		
		return imp;
	}
	public static Module readXMLModule(Document doc, Env env) {
		Module me= null;
		try {
			me = (Module)ModelElement.parseXML(env, doc.getRootElement());
		} catch (ModelException e1) {
			if (e1.getErrorTag().equals(ErrTag.ERROR)) {
				e1.printStackTrace();
				return null;
			}

			System.out.println(e1.toString());
		}
		if (null == me) {
			return null;
		}
		
		return me;
	}	
	public static Module readYinModule(String module, Env env) {
		if (null == module) {
			return null;
		}
		Module imp = null;
		Document doc = null;
		SAXBuilder sax = new SAXBuilder();
		module = removeUTF8BOM(module);
		ByteArrayInputStream bi = new ByteArrayInputStream(module.getBytes(Charset.forName("utf-8")));
		//StringReader sr = new StringReader(module);
		try {
			doc = sax.build(bi);
		} catch (JDOMException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		if (null == doc) {
			return null;
		}

		ModelElement me = null;
		try {
			me = ModelElement.parseYin(env, doc.getRootElement());
		} catch (ModelException e1) {
			if (e1.getErrorTag().equals(ErrTag.ERROR)) {
				e1.printStackTrace();
				return null;
			}

			System.out.println(e1.toString());
		}
		if (null == me) {
			return null;
		}
		if (me instanceof MainModule) {
			imp = (MainModule) me;
		} else if (me instanceof SubModule) {
			imp = (SubModule) me;
		} else {
			return null;
		}
		
		return imp;
	}
	
	public static Module readYinModule(File file, Env env)  {

		if (null == file) {
			return null;
		}
		String module;
		try {
			module = FileUtil.readFile2String(file);
			return readYinModule(module, env);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		return null;
	}

//	public static Module openModule(String format, String module,
//			ArrayList<String> relatedModules) {
//		if (null == format) {
//			return null;
//		}
//		if ((!format.equals(FORMAT_YANG)) && (!format.equals(FORMAT_XML))
//				&& (!format.equals(FORMAT_YIN))) {
//			return null;
//		}
//		if (null == module) {
//			return null;
//		}
//
//		Module moduleM = null;
//
//		if (format.equals(FORMAT_YANG)) {
//			Env env = new Env();
//			// load related modules
//			if (null != relatedModules) {
//				int size = relatedModules.size();
//				for (int i = 0; i < size; i++) {
//					String m = relatedModules.get(i);
//					if (null != m) {
//						Env mEnv = env.cloneExtra();
//
//						Module mod = readYangModule(m, mEnv);
//						if (null == mod) {
//							continue;
//						}
//						if (mod instanceof MainModule) {
//							env.addMainModule((MainModule) mod);
//						} else {
//							env.addSubModule((SubModule) mod);
//						}
//					}
//				}
//			}
//			// load module
//			moduleM = readYangModule(module, env);
//		} else if (format.equals(FORMAT_XML)) {
//			Env env = new Env();
//			// load related modules
//			if (null != relatedModules) {
//				int size = relatedModules.size();
//				for (int i = 0; i < size; i++) {
//					String m = relatedModules.get(i);
//					if (null != m) {
//						Env mEnv = env.cloneExtra();
//
//						Module mod = readXMLModule(m, mEnv);
//						if (null == mod) {
//							continue;
//						}
//						if (mod instanceof MainModule) {
//							env.addMainModule((MainModule) mod);
//						} else {
//							env.addSubModule((SubModule) mod);
//						}
//					}
//				}
//			}
//			// load module
//			moduleM = readXMLModule(module, env);
//
//		} else {
//
//		}
//		
//		return moduleM;
//	}
	public static Module importModule(String format, String module,
			ArrayList<Module> relatedModules){
		Module moduleM = null;
		moduleM = openModule(format , module , relatedModules);
		Validator validator = moduleM.validate();
		if(!validator.isValid()){
			return null;
		}
		return moduleM;
	}
	public static Module openModule(String format, String module,
			ArrayList<Module> relatedModules) {
		if (null == format) {
			return null;
		}
		if ((!format.equals(FORMAT_YANG)) && (!format.equals(FORMAT_XML))
				&& (!format.equals(FORMAT_YIN))) {
			return null;
		}
		if (null == module) {
			return null;
		}

		Module moduleM = null;
		Env env = new Env();
		// load related modules
		if (null != relatedModules) {
			int size = relatedModules.size();
			for (int i = 0; i < size; i++) {
				Module m = relatedModules.get(i);
				if (null != m) {

					if (m instanceof MainModule) {
						env.addMainModule((MainModule) m);
					} else {
						env.addSubModule((SubModule) m);
					}
				}
			}
		}
		if (format.equals(FORMAT_YANG)) {
			// load module
			moduleM = readYangModule(module, env);
		} else if (format.equals(FORMAT_XML)) {		
			// load module
			moduleM = readXMLModule(module, env);

		} else {
			// load module
			moduleM = readYinModule(module, env);
		}
		
		return moduleM;
	}
	public static Module openXMLModule(Document module,
			ArrayList<Module> relatedModules) {
		if (null == module) {
			return null;
		}

		Module moduleM = null;
		Env env = new Env();
		// load related modules
		if (null != relatedModules) {
			int size = relatedModules.size();
			for (int i = 0; i < size; i++) {
				Module m = relatedModules.get(i);
				if (null != m) {

					if (m instanceof MainModule) {
						env.addMainModule((MainModule) m);
					} else {
						env.addSubModule((SubModule) m);
					}
				}
			}
		}
			moduleM = readXMLModule(module, env);

	
		
		return moduleM;
	}
	public static String outModule(String format, Module module){
		if (null == format) {
			return null;
		}
		if ((!format.equals(FORMAT_YANG)) && (!format.equals(FORMAT_XML))
				&& (!format.equals(FORMAT_YIN))) {
			return null;
		}
		if (null == module) {
			return null;
		}
		
		

		String outString = null;

		if (format.equals(FORMAT_YANG)) {
			YangFormatter formatter = new YangFormatter();
			formatter.setPrettyFormatter();
			if (module instanceof MainModule) {
				
				outString = ((MainModule) (module)).toYANGString(formatter);
			} 
			else {
				outString = ((SubModule) (module)).toYANGString(formatter);
			}
		} 
		else if (format.equals(FORMAT_XML)) {
			if (module instanceof MainModule) {
				outString = ((MainModule) (module)).toXMLString();
			} 
			else {
				outString = ((SubModule) (module)).toXMLString();
			}

		} 
		else {
			if (module instanceof MainModule) {
				outString = ((MainModule) (module)).toYINString();
			} 
			else {
				outString = ((SubModule) (module)).toYINString();
			}
		}
		
		return outString;
	}
	public static String saveModule(Module module){
		 return outModule(FORMAT_YANG,module);
	}

	public static String exportModule(String format, Module module) {
		Validator validator = module.validate();
		if (!validator.isValid()){
			System.out.println(validator.toString());
			//return null;
		}
		return outModule(format,module);

	}
	public static MainModule createMainModule(String moduleName,
			ArrayList<Module> relatedModules) throws ModelException{
		if (null == moduleName){
			return null;
		}
		Env env = new Env();
		if (null != relatedModules){
			int size = relatedModules.size();
			for (int i = 0; i < size; i++){
				Module m = relatedModules.get(i);
				if (null == m){
					continue;
				}
				
				if (m instanceof MainModule){
					env.addMainModule((MainModule)m);
				}
				else {
					env.addSubModule((SubModule)m);
				}
			}
		}
		
			
		return (MainModule)MainModule.create(env, moduleName);
		
	}
	public static SubModule createSubModule(String moduleName,String belongsto,
			String prefix,ArrayList<Module> relatedModules) throws ModelException{
		if (null == moduleName){
			return null;
		}
		Env env = new Env();
		if (null != relatedModules){
			int size = relatedModules.size();
			for (int i = 0; i < size; i++){
				Module m = relatedModules.get(i);
				if (null == m){
					continue;
				}
				
				if (m instanceof MainModule){
					env.addMainModule((MainModule)m);
				}
				else {
					env.addSubModule((SubModule)m);
				}
			}
		}
		
			
		return new SubModule(env,moduleName,belongsto,prefix);
		
	}
    public static void save2File(String buffer, String out){
    	if (null == buffer)
    		return;
    	if (null == out){
    		return;
    	}
    	if ("console".equals(out)){
    		System.out.println(buffer);
    		return;
    	}
		FileWriter fw = null;
		try {
			fw = new FileWriter(out);
			try {
				fw.write(buffer);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				fw.close();
			}
			fw.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return;
    }
    public static File getFile(File[]files, String name){
    	if (null == files){
    		return null;
    	}
    	if (null == name){
    		return null;
    	}
    	int length = files.length;
    	for (int i = 0; i < length; i++){
    		File file = files[i];
    		if (null == file){
    			continue;
    		}
    		
    		if (file.getName().equals(name)){
    			return file;
    		}
    	}
    	
    	return null;
    }
    /**
     * 从模型xml所在的路径中根据模型加载xml中的顺序逐一加载成模型
     * @param path
     * @param loadList
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static ModulesLoad readModules(String path,String loadList) throws JDOMException, IOException{
    	if (null == path){
    		return null;
    	}
    	
    	if (null == loadList){
    		return null;
    	}
    	
    	if(!loadList.endsWith(".xml")){
    		return null;
    	}
    	
    	File modulesPath=new File(path);
        if(!modulesPath.exists()||!modulesPath.isDirectory()){
        	System.out.println("Path:"  + modulesPath.getAbsolutePath()+ " is invalid path!" );
        	throw new FileNotFoundException();
		}
		// 读取模型加载xml
		SAXBuilder builder = new SAXBuilder();
		Document modulesLoadDocument = builder.build(loadList);
		if (null == modulesLoadDocument) {
			return null;
		}
		ModulesLoad modulesLoad = new ModulesLoad();
		modulesLoad.readXml(modulesLoadDocument);

		// 根据模型加载的读取结果逐一按序加载模型文件
		int modulesSize = modulesLoad.getModulesNumber();
		if (0 == modulesSize) {
			return null;
		}
		File[] files = modulesPath.listFiles();
		if (null == files) {
			return null;
		}
		// 初始化环境变量
		Env env = new Env();

		//ArrayList<ModuleLoad> modules = null;
		for (int i = 0; i < modulesSize; i++) {
			ModuleLoad moduleLoad = modulesLoad.getModule(i);
			if (null == moduleLoad) {
				continue;
			}

			// 获取文件名
			String filename = moduleLoad.getFileName();
			if (null == filename) {
				continue;
			}

			File file = getFile(files, filename);
			if (null == file) {
				continue;
			}
			String moduleString = FileUtil.readFile2String(file);
			if (null == moduleString){
				continue;
			}
			Module module = null;
			if (filename.endsWith(".yang")){
				module = readYangModule(moduleString, env);
			}
			else if (filename.endsWith(".yin")){
				module = readYinModule(moduleString, env);
			}
			else {
				continue;
			}
			
			if (null == module) {
				continue;
			}
			
			moduleLoad.setModule(module);
			moduleLoad.setFile(file);
			// 将本次生成module加入env
			env.addMainModule((MainModule) module);
			// 暂时不考虑子模块问题

			env = env.cloneExtra();
		}

		return modulesLoad;
    	
    }
 
    /**
     * 从模型xml所在的路径中根据模型加载xml中的顺序逐一加载成模型
     * @param path
     * @param loadList
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static ModulesLoad readModules(String path) throws JDOMException, IOException{
    	if (null == path){
    		return null;
    	}

    	File modulesPath=new File(path);
        if(!modulesPath.exists()||!modulesPath.isDirectory()){
        	System.out.println("Path:"  + modulesPath.getAbsolutePath()+ " is invalid path!" );
        	throw new FileNotFoundException();
		}
		
		File[] files = modulesPath.listFiles();
		if (null == files) {
			return null;
		}
		int srcFilesNumber = files.length;
		int srcParsedFileNumber = 0;
		int parsedCount = 0;
		ModulesLoad modulesLoad = new ModulesLoad();
		
		// 初始化环境变量
		Env env = new Env();
		
		do {
			parsedCount = 0;
			for (int i = 0 ; i < srcFilesNumber; i++){
				File file = files[i];
				if (null == file) {
					continue;
				}
				String filename = file.getName();
				//已经读过的，就不要再读了
				if (null != modulesLoad.getModuleByFilename(file.getAbsolutePath(), filename)){
					continue;
				}
			
				Module module = null;
				
				if (filename.endsWith(".yang")){
					module = readYangModule(file, env);
				}
				else if (filename.endsWith(".yin")){
					module = readYinModule(file, env);
				}
				else {
					continue;
				}
				
				if (null == module) {
					continue;
				}
//				Validator validator = module.validate();
//				if (!validator.isValid()){
//					continue;
//				}
				ModuleLoad moduleLoad = new ModuleLoad();
				moduleLoad.setName(module.getName());
				moduleLoad.setRevisionDate(module.getCurRevisionDate());
				moduleLoad.setPath(file.getAbsolutePath());
				moduleLoad.setFileName(filename);
				moduleLoad.setModule(module);
				moduleLoad.setFile(file);
				modulesLoad.addModule(moduleLoad);
				// 将本次生成module加入env
				env.addMainModule((MainModule) module);
				// 暂时不考虑子模块问题

				env = env.cloneExtra();
				srcParsedFileNumber++;
				parsedCount++;
			}
			
		}while((srcParsedFileNumber != srcFilesNumber)
				&&(0 != parsedCount) );
		
		return modulesLoad;
    	
    }
    
    /**
     * 把指定目录下的NETCONF的模型，完全转换为yang模型
     * @param path
     * @param loadList
     * @throws IOException 
     * @throws JDOMException 
     */
    public static void yangFormatter(String srcPath,String loadList,String dstPath) throws JDOMException, IOException{
    	if (null == srcPath){
    		return;
    	}
    	
    	if (null == dstPath){
    		return;
    	}
    	
    	if (null == loadList){
    		return;
    	}
    	
    	File srcDir=new File(srcPath);
        if(!srcDir.exists()||!srcDir.isDirectory()){
        	System.out.println("Path:"  + srcDir.getAbsolutePath()+ " is invalid path!" );
        	throw new FileNotFoundException();
		}
        
        File dstDir= new File(dstPath);
        if (dstDir.exists()){
        	if (!dstDir.isDirectory()){
        		System.out.println("Path:"  + dstDir.getAbsolutePath()+ " is invalid path!" );
            	throw new FileNotFoundException();
        	}
        }
        else {
        	dstDir.mkdirs();
        }
        
        ModulesLoad modulesLoad = readModules(srcPath, loadList);
        if (null == modulesLoad){
        	return;
        }
        
        int modulesSize = modulesLoad.getModulesNumber();
		for (int i = 0 ; i < modulesSize; i++){
			ModuleLoad moduleLoad= modulesLoad.getModule(i);
			if (null == moduleLoad){
				continue;
			}
			
				
			Module module= moduleLoad.getModule();
			if (null == module){
				continue;
			}
			String revision= module.getCurRevisionDate();
			String filename = module.getName()+"@"+revision+".yang";
			
			//生成对应YANG模型
			String moduleyangString= outModule(FORMAT_YANG,module);
			File newFile = new File(dstDir,filename);
			File fileBak = null;
			if (newFile.exists()){
				//先把旧的文件拷贝一份			 
				fileBak = new File(dstDir,filename+".bak");
				newFile.renameTo(fileBak);
				//删除掉旧的文件
				newFile.delete();
			}
			
			if(FileUtil.writeUtf8File(moduleyangString, newFile)){
				//如果写文件成功，则删除备份文件
				if (null != fileBak){
					fileBak.delete();
				}				
			}
			else {
				if (null != fileBak){
					fileBak.renameTo(newFile);
					fileBak.delete();
				}
				
			}
		}
        
    }
    
    /**
     * 把指定目录下的NETCONF的模型，完全转换为yang模型
     * @param path
     * @param loadList
     * @throws IOException 
     * @throws JDOMException 
     */
    public static void yangFormatter(String srcPath,String dstPath) throws JDOMException, IOException{
    	if (null == srcPath){
    		return;
    	}
    	
    	if (null == dstPath){
    		return;
    	}

    	File srcDir=new File(srcPath);
        if(!srcDir.exists()||!srcDir.isDirectory()){
        	System.out.println("Path:"  + srcDir.getAbsolutePath()+ " is invalid path!" );
        	throw new FileNotFoundException();
		}
        
        File dstDir= new File(dstPath);
        if (dstDir.exists()){
        	if (!dstDir.isDirectory()){
        		System.out.println("Path:"  + dstDir.getAbsolutePath()+ " is invalid path!" );
            	throw new FileNotFoundException();
        	}
        }
        else {
        	dstDir.mkdirs();
        }
        
        ModulesLoad modulesLoad = readModules(srcPath);
        if (null == modulesLoad){
        	return;
        }
        
        int modulesSize = modulesLoad.getModulesNumber();
		for (int i = 0 ; i < modulesSize; i++){
			ModuleLoad moduleLoad= modulesLoad.getModule(i);
			if (null == moduleLoad){
				continue;
			}
			
				
			Module module= moduleLoad.getModule();
			if (null == module){
				continue;
			}
			String revision= module.getCurRevisionDate();
			String filename = module.getName()+"@"+revision+".yang";
			
			//生成对应YANG模型
			String moduleyangString= outModule(FORMAT_YANG,module);
			File newFile = new File(dstDir,filename);
			File fileBak = null;
			if (newFile.exists()){
				//先把旧的文件拷贝一份			 
				fileBak = new File(dstDir,filename+".bak");
				newFile.renameTo(fileBak);
				//删除掉旧的文件
				newFile.delete();
			}
			
			if(FileUtil.writeUtf8File(moduleyangString, newFile)){
				//如果写文件成功，则删除备份文件
				if (null != fileBak){
					fileBak.delete();
				}				
			}
			else {
				if (null != fileBak){
					fileBak.renameTo(newFile);
					fileBak.delete();
				}
				
			}
		}
        
    }
	/**
	 * usage
	 * args[0]:"yang2xml","xml2yang","openyang","openxml","save","export2yang"
	 * ,"export2yin" args[1] sourcefile args[2] outputfile ...
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		if (null == args) {
			return;
		}
		String actionType = args[0];
		
		int length = args.length;
		if (null == actionType) {
			return;
		}
		if (actionType.equals("yang2xml")
				) {
			String sourceFile = args[1];
			String destFile = args[2];
			if (null == sourceFile || null == destFile) {
				return;
			}
			
			String yangStr = null;
			ArrayList<Module> relatedModules = null;
			if (length > 3) {
				Env mEnv = new Env();
				for (int i = 3; i < length; i++) {
					if (null != args[i]) {
						if (null == relatedModules) {
							relatedModules = new ArrayList<Module>(1);
						}
						Module m = null;
						try {
							
							if (args[i].endsWith(".xml")){
								SAXBuilder builder = new SAXBuilder();
								Document myDocument = builder.build(args[i]);
								//String module = myDocument.toString();
								m = readXMLModule(myDocument, mEnv);
							}
							else if (args[i].endsWith(".yang")){
								yangStr = FileUtil.readFile2String(args[i]);
								m = readYangModule(yangStr, mEnv);
							}
							else {
								throw new Exception("unsupport file type!!!");
							}
							
						} catch (Exception e2) {
							// TODO Auto-generated catch block
							e2.printStackTrace();

						}
						if (null != m) {
							relatedModules.add(m);
							if (m instanceof MainModule) {
								mEnv.addMainModule((MainModule) m);
						    } 
							else {
								mEnv.addSubModule((SubModule) m);
							}
							mEnv = mEnv.cloneExtra();
							
						}

					}
				}
			}
			try {
				yangStr = FileUtil.readFile2String(sourceFile);
			} catch (IOException e2) {
				// TODO Auto-generated catch block
				e2.printStackTrace();

			}
			if (null == yangStr) {
				return;
			}
			Module m = openModule(FORMAT_YANG, yangStr, relatedModules);
			if (actionType.equals("yang2xml")){
				save2File(exportModule(FORMAT_XML, m),destFile);
			}
			else {
				save2File(exportModule(FORMAT_YANG, m),destFile);
			}
			
			return;
		} else if (actionType.equals("validate")) {
			String type = args[1];
			String sourceFile = args[2];
			String destFile = args[3];
			if (null == type || null == sourceFile || null == destFile) {
				return;
			}
			
			String yangStr = null;
			ArrayList<Module> relatedModules = null;
			if (length > 4) {
				Env mEnv = new Env();
				for (int i = 4; i < length; i++) {
					if (null != args[i]) {
						if (null == relatedModules) {
							relatedModules = new ArrayList<Module>(1);
						}
						Module m = null;
						try {
							
							if (args[i].endsWith(".xml")){
								SAXBuilder builder = new SAXBuilder();
								Document myDocument = builder.build(args[i]);
								//String module = myDocument.toString();
								m = readXMLModule(myDocument, mEnv);
							}
							else if (args[i].endsWith(".yang")){
								yangStr = FileUtil.readFile2String(args[i]);
								m = readYangModule(yangStr, mEnv);
							}
							else {
								throw new Exception("unsupport file type!!!");
							}
							
						} catch (Exception e2) {
							// TODO Auto-generated catch block
							e2.printStackTrace();

						}
						if (null != m) {
							relatedModules.add(m);
							if (m instanceof MainModule) {
								mEnv.addMainModule((MainModule) m);
						    } 
							else {
								mEnv.addSubModule((SubModule) m);
							}
							mEnv = mEnv.cloneExtra();
							
						}

					}
				}
			}
			Module m = null;
			if (type.equalsIgnoreCase(FORMAT_YANG)){
				try {
					yangStr = FileUtil.readFile2String(sourceFile);
				} catch (IOException e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();

				}
				if (null == yangStr) {
					return;
				}
				m = openModule(FORMAT_YANG, yangStr, relatedModules);
			}
			else if (type.equalsIgnoreCase(FORMAT_XML)){
				//String module = null;
					SAXBuilder builder = new SAXBuilder();
					Document myDocument = null;
					try {
						try {
							myDocument = builder.build(sourceFile);
							//module = myDocument.toString();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} catch (JDOMException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				
				m = openXMLModule(myDocument, relatedModules);
			}
			if (null == m){
				return;
			}
			Validator validator = m.validate();
			if (destFile.equals("console")){
				System.out.println(validator.toString());
			}
			else {
				save2File(validator.toString(), destFile);
			}
			return;
		}
		else if (actionType.equalsIgnoreCase("yangformatter")){
			if(length == 4){
				String srcpath = args[1];
				String loadlist= args[2];
				String dstpath= args[3];
				try {
					yangFormatter(srcpath, loadlist, dstpath);
				} catch (JDOMException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			else if (length == 3){
				String srcpath = args[1];
				String dstpath= args[2];
				try {
					yangFormatter(srcpath,dstpath);
				} catch (JDOMException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
	}

}
